export interface IntensityMetrics {
  amplitude: number;
  durationRatio: number;
  frequencyRatio: number;
  overallScore: number;
  completionRatio: number;
  elapsedSeconds: number;
  repCount: number;
  isActive: boolean;
  movementPoints: number;
  /** 当前正在填充的番茄索引 (0-based) */
  currentTomatoIndex: number;
  /** 当前番茄的填充进度 0-1 */
  currentTomatoProgress: number;
  /** 已完成的番茄数量 */
  completedTomatoes: number;
}

export const INITIAL_INTENSITY_METRICS: IntensityMetrics = {
  amplitude: 0,
  durationRatio: 0,
  frequencyRatio: 0,
  overallScore: 0,
  completionRatio: 0,
  elapsedSeconds: 0,
  repCount: 0,
  isActive: false,
  movementPoints: 0,
  currentTomatoIndex: 0,
  currentTomatoProgress: 0,
  completedTomatoes: 0,
};

const ACTIVE_THRESHOLD = 0.15; // 降低活动阈值，更容易检测到运动

export class IntensityAnalyzer {
  private activeDurationSeconds = 0;
  private startTime: number | null = null;
  private lastTimestamp: number | null = null;
  private repCount = 0;
  private lastRepCount = 0;
  private inPeak = false;
  private movementPoints = 0;

  private targetActiveDurationSeconds = 120; // 2 minutes of active movement
  private targetReps = 20;
  private movementGoal = 120;

  // 番茄果相关状态
  private totalTomatoes = 5; // 总共5个番茄果
  private pointsPerTomato = 8; // 每个番茄需要8点运动量（测试模式，进一步降低）
  private completedTomatoes = 0; // 已完成的番茄数
  private accumulatedPoints = 0; // 不可逆累积的运动点数

  reset() {
    this.activeDurationSeconds = 0;
    this.startTime = null;
    this.lastTimestamp = null;
    this.repCount = 0;
    this.lastRepCount = 0;
    this.inPeak = false;
    this.movementPoints = 0;
    this.completedTomatoes = 0;
    this.accumulatedPoints = 0;
  }

  analyze(landmarks: any[], timestamp: number): IntensityMetrics {
    if (!landmarks || landmarks.length < 33) {
      return { ...INITIAL_INTENSITY_METRICS };
    }

    if (!this.startTime) {
      this.startTime = timestamp;
    }

    if (!this.lastTimestamp) {
      this.lastTimestamp = timestamp;
    }

    const deltaSeconds = (timestamp - this.lastTimestamp) / 1000;
    this.lastTimestamp = timestamp;

    const amplitude = this.computeAmplitude(landmarks);
    const isActive = amplitude > ACTIVE_THRESHOLD;

    if (isActive) {
      this.activeDurationSeconds += Math.max(0, deltaSeconds);
      this.movementPoints += amplitude * deltaSeconds * 20; // amplitude contribution
      
      // 不可逆累积运动点数 - 提高累积速度（测试模式）
      const pointsToAdd = amplitude * deltaSeconds * 30; // 从20提高到30
      this.accumulatedPoints += pointsToAdd;
      
      // 调试日志
      if (pointsToAdd > 0) {
        console.log(`[运动检测] 幅度: ${(amplitude * 100).toFixed(1)}%, 累积点数: ${this.accumulatedPoints.toFixed(2)}, 当前番茄: ${Math.floor(this.accumulatedPoints / this.pointsPerTomato)}, 进度: ${((this.accumulatedPoints % this.pointsPerTomato) / this.pointsPerTomato * 100).toFixed(1)}%`);
      }
    }

    this.updateRepCount(amplitude);

    if (this.repCount > this.lastRepCount) {
      const repIncrement = this.repCount - this.lastRepCount;
      this.movementPoints += repIncrement * 8;
      
      // 动作计数也累积到不可逆点数 - 提高奖励
      const repPoints = repIncrement * 10; // 从8提高到10
      this.accumulatedPoints += repPoints;
      this.lastRepCount = this.repCount;
      
      console.log(`[动作完成] 第${this.repCount}次动作，获得${repPoints}点，总点数: ${this.accumulatedPoints.toFixed(2)}`);
    }

    // 计算当前正在填充的番茄索引和进度
    const totalPoints = this.accumulatedPoints;
    const currentTomatoIndex = Math.min(
      Math.floor(totalPoints / this.pointsPerTomato),
      this.totalTomatoes - 1
    );
    const pointsInCurrentTomato = totalPoints % this.pointsPerTomato;
    const currentTomatoProgress = Math.min(pointsInCurrentTomato / this.pointsPerTomato, 1);
    
    // 更新已完成的番茄数
    this.completedTomatoes = Math.floor(totalPoints / this.pointsPerTomato);

    const frequencyRatio = Math.min(1, this.repCount / this.targetReps);
    const durationRatio = Math.min(1, this.activeDurationSeconds / this.targetActiveDurationSeconds);

    const overallScore = Math.min(
      1,
      amplitude * 0.45 + frequencyRatio * 0.35 + durationRatio * 0.2
    );

    // 总体完成度基于番茄数
    const completionRatio = Math.min(1, (this.completedTomatoes + currentTomatoProgress) / this.totalTomatoes);

    return {
      amplitude,
      durationRatio,
      frequencyRatio,
      overallScore,
      completionRatio,
      elapsedSeconds: this.activeDurationSeconds,
      repCount: this.repCount,
      isActive,
      movementPoints: this.movementPoints,
      currentTomatoIndex,
      currentTomatoProgress,
      completedTomatoes: this.completedTomatoes,
    };
  }

  private computeAmplitude(landmarks: any[]): number {
    const leftShoulder = landmarks[11];
    const rightShoulder = landmarks[12];
    const leftHip = landmarks[23];
    const rightHip = landmarks[24];
    const leftWrist = landmarks[15];
    const rightWrist = landmarks[16];
    const leftKnee = landmarks[25];
    const rightKnee = landmarks[26];

    if (!leftShoulder || !rightShoulder || !leftHip || !rightHip) {
      return 0;
    }

    const shoulderY = (leftShoulder.y + rightShoulder.y) / 2;
    const hipY = (leftHip.y + rightHip.y) / 2;

    let upperReach = 0;
    if (leftWrist && rightWrist) {
      const wristY = (leftWrist.y + rightWrist.y) / 2;
      upperReach = Math.max(0, (shoulderY - wristY) * 2.2);
    }

    let lowerLift = 0;
    if (leftKnee && rightKnee) {
      const kneeY = Math.min(leftKnee.y, rightKnee.y);
      lowerLift = Math.max(0, (hipY - kneeY) * 1.8);
    }

    return Math.min(1, Math.max(upperReach, lowerLift));
  }

  private updateRepCount(amplitude: number) {
    const peakThreshold = 0.4; // 降低峰值阈值，从0.6降到0.4
    const releaseThreshold = 0.2; // 降低释放阈值，从0.35降到0.2

    if (amplitude > peakThreshold && !this.inPeak) {
      this.inPeak = true;
      this.repCount += 1;
      console.log(`[动作峰值] 检测到第${this.repCount}次动作，幅度: ${(amplitude * 100).toFixed(1)}%`);
    }

    if (amplitude < releaseThreshold && this.inPeak) {
      this.inPeak = false;
    }
  }
}
